package com.xc.ksxt.service;

import com.google.common.base.Optional;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Lists;
import com.xc.ksxt.entity.LibEntity;
import com.xc.ksxt.vo.LibVO;
import com.xc.common.object.PageInfo;
import com.xc.common.tool.BeanAid;
import com.xc.db.Tables;
import com.xc.db.tables.Lib;
import com.xc.db.tables.records.LibRecord;
import java.util.List;
import java.util.concurrent.ExecutionException;
import org.jooq.Condition;
import org.jooq.DSLContext;
import org.jooq.InsertResultStep;
import org.jooq.Record;
import org.jooq.Result;
import org.jooq.SelectForUpdateStep;
import org.jooq.SelectSeekStepN;
import org.jooq.SortField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class LibService {
	@Autowired
	private DSLContext dsl;
	private Lib LIBTB = Lib.LIB.as("LIBTB");
	public Lib getTable() {
		return LIBTB;
	}
	public Result<Record> select(Condition whr, PageInfo<LibEntity> pageInfo, SortField<?>... orderby) {
		SelectSeekStepN<Record> seek = dsl.select().from(LIBTB).where(whr).orderBy(orderby);
		Result<Record> result = null;
		if (pageInfo != null) {
			SelectForUpdateStep<Record> su = seek.limit(pageInfo.getLimit()).offset(pageInfo.getBeginNum());
			result = su.fetch();
		} else {
			result = seek.fetch();
		}
		if (pageInfo != null) {
			pageInfo.setResult(result);
			pageInfo.setList(result.into(LibEntity.class));
		}
		return result;
	}
	public Result<Record> selectVO(Condition whr, PageInfo<LibVO> pageInfo, SortField<?>... orderby) {
		SelectSeekStepN<Record> seek = dsl.select().from(LIBTB).where(whr).orderBy(orderby);
		Result<Record> result = null;
		if (pageInfo != null) {
			SelectForUpdateStep<Record> su = seek.limit(pageInfo.getLimit()).offset(pageInfo.getBeginNum());
			result = su.fetch();
		} else {
			result = seek.fetch();
		}
		if (pageInfo != null) {
			pageInfo.setResult(result);
			pageInfo.setList(result.into(LibVO.class));
		}
		return result;
	}

	public List<LibEntity> select(Condition whr, SortField<?>... orderby) {
		Result<Record> result = dsl.select().from(LIBTB).where(whr).orderBy(orderby).fetch();
		List<LibEntity> list = Lists.newArrayList();
		if (result.size() > 0) {
			list = result.into(LibEntity.class);
		}
		return list;
	}

	public Long count(Condition cond) {
		Long count = dsl.selectCount().from(LIBTB).where(cond).fetchOneInto(Long.class);
		return count;
	}

	public Record getRecordById(Integer id) {
		Record record = dsl.select().from(LIBTB).where(LIBTB.ID.eq(id)).fetchOne();
		return record;
	}

	public LibEntity getEntityById(Integer id) {
		Record r = getRecordById(id);
		if(r==null) {
			return null;
		}
		LibEntity entity = r.into(LibEntity.class);
		return entity;
	}

	public Integer update(LibEntity entity) {
		LibRecord record = new LibRecord();
		record.from(entity);
		dsl.executeUpdate(record);
		invalidateCache(entity.getId());
		return Integer.valueOf(entity.getId());
	}

	public Integer insert(LibEntity entity) {
		LibRecord record = new LibRecord();
		record.from(entity);
		InsertResultStep<LibRecord> su = dsl.insertInto(Tables.LIB).set(record).returning(getTable().ID);
		int id = su.fetchOne().getId();
		entity.setId(id);
		invalidateCache(id);
		return id;
	}

	public Integer save(LibEntity entity) {
		if (entity.getId()==null) {
			return insert(entity);
		}
		LibEntity entity2 = getEntityById(Integer.valueOf(entity.getId()));
		if(entity2==null) {
			return insert(entity);
		}
		return update(entity);
	}

	public void deleteById(Integer id) {
		dsl.delete(LIBTB).where(LIBTB.ID.eq(id)).execute();
		invalidateCache(id);
	}
	public static LoadingCache<Integer, Optional<LibEntity>> cache = CacheBuilder.newBuilder().maximumSize(500).build(
            new CacheLoader<Integer, Optional<LibEntity>>() {
                public Optional<LibEntity> load(Integer id) {
                	LibService service = BeanAid.getBean(LibService.class);
                    LibEntity user = service.getEntityById(id);
                    return Optional.fromNullable(user);
                }
    });
	public static LibEntity getFromCaches(Integer key) {
        if (key == null) {
            return null;
        }
        try {
            return cache.get(key).orNull();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return null;
    }
	public static LibEntity getFromCaches(String key) {
		if (key == null) {
			return null;
		}
		try {
			return cache.get(Integer.valueOf(key)).orNull();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
		return null;
	}
	public static void invalidateCache(String id) {
    	cache.invalidate(Integer.valueOf(id));
    }
    public static void invalidateCache(Integer id) {
    	cache.invalidate(id);
    }
}
